﻿@using Gurux.DLMS.AMI.Script
@using Gurux.DLMS.AMI.Shared
@using Gurux.DLMS.AMI.Shared.DIs
@using Microsoft.AspNetCore.Authorization
@using Microsoft.AspNetCore.Components.WebAssembly.Authentication
@using Gurux.DLMS.AMI.Shared.DTOs
@using Gurux.DLMS.AMI.Shared.Rest
@using Gurux.DLMS.AMI.Shared.Enums
@using Gurux.DLMS.AMI.Module
@using System.Globalization
@using System.Text
@using System.Text.Json
@using Gurux.DLMS.AMI.Script.Pages
@using Microsoft.AspNetCore.SignalR.Client
@using Microsoft.Extensions.Logging

@namespace Gurux.DLMS.AMI.Client.Pages.Config

@inject NavigationManager NavigationManager
@implements IDisposable
@inject HttpClient Http
@inject IGXNotifier Notifier
@implements IGXConfigUpdate

@if (_settings != null)
{
    <h2>Client notifications</h2>
    <input type="search" value="@SearchText"
           @oninput="@Search" placeholder="Search by type" />
    <EditForm Model="@_settings">
        <table class="table table-striped" width="100%">
            <thead>
                <tr>
                    <th>
                        <Tooltip Title="@ToolTip">
                            <input type="checkbox" @onchange="@((ChangeEventArgs __e) => ToggleAll(Convert.ToBoolean(__e.Value)))" />
                        </Tooltip>
                    </th>
                    <th>@Properties.Resources.Name</th>
                </tr>
            </thead>
            <tbody>
                @foreach (var it in Notifications)
                {
                    <tr class=@(GetSelectedClass(it)) @onclick="@(()=>RowSelected(it))">
                        <td>
                            <div class="form-check form-switch">
                                <input class="form-check-input" type="checkbox"
                                       checked="@IsEnabled(@it)"
                                       @onchange="@((e) => UpdateIgnoredState(@it, e.Value))" />
                            </div>
                        </td>
                        <td>
                            @it
                        </td>
                    </tr>
                }
            </tbody>
        </table>
    </EditForm>
}

@code {

    /// <inheritdoc/>
    public void Update()
    {
        if (!string.IsNullOrEmpty(Parent?.Active?.Settings))
        {
            _settings = JsonSerializer.Deserialize<PerformanceSettings>(Parent.Active.Settings);
        }
        StateHasChanged();
    }

    /// <summary>
    /// Parent component.
    /// </summary>
    [Parameter]
    public Gurux.DLMS.AMI.Client.Pages.Config.Configurations? Parent { get; set; }

    PerformanceSettings? _settings;

    protected string ToolTip
    {
        get
        {
            return _allSelected ? "Disable all notifications" : "Enable all notifications.";
        }
    }


    protected string GetSelectedClass(string selected)
    {
        return selected == _active ? "table-info" : "table-striped";
    }

    protected void RowSelected(string selected)
    {
        _active = selected;
    }
    private string? _active;
    private string SearchText = "";
    private bool _allSelected = false;

    IEnumerable<string> Notifications = ClientHelpers.GetNotifications(false);

    private void ToggleAll(bool select)
    {
        _allSelected = select;
        if (_settings != null)
        {
            if (select)
            {
                _settings.IgnoreNotification = null;
            }
            else
            {
                _settings.IgnoreNotification = Notifications.ToArray();
            }
        }
    }

    /// <summary>
    /// Search from notifications.
    /// </summary>
    private void Search(ChangeEventArgs args)
    {
        String? value = Convert.ToString(args.Value);
        Notifications = ClientHelpers.GetNotifications(false);
        if (!string.IsNullOrEmpty(value))
        {
            value = value.ToLower();
            List<string> tmp = new List<string>();
            foreach (var it in Notifications)
            {
                if (it.Contains(value))
                {
                    tmp.Add(it);
                }
            }
            Notifications = tmp;
        }
        StateHasChanged();
    }

    private bool IsEnabled(string? value)
    {
        return _settings?.IgnoreNotification == null ||
            !_settings.IgnoreNotification.Contains(value);
    }

    private void UpdateIgnoredState(string value, object? ignored)
    {
        if (_settings != null)
        {
            List<string> list = new List<string>();
            if (_settings.IgnoreNotification != null)
            {
                list.AddRange(_settings.IgnoreNotification);
            }
            if (Convert.ToBoolean(ignored))
            {
                list.Remove(value);
            }
            else
            {
                list.Add(value);
            }
            _settings.IgnoreNotification = list.ToArray();
        }
    }

    protected override void OnInitialized()
    {
        try
        {
            if (Notifier == null)
            {
                throw new ArgumentException(Properties.Resources.InvalidNotifier);
            }
            Notifier.ProgressStart();
            Notifier.ClearStatus();
            Notifier.On<IEnumerable<GXConfiguration>>(this, nameof(IGXHubEvents.ConfigurationSave), (configurations) =>
            {
                if (configurations != null)
                {
                    foreach (var it in configurations)
                    {
                        if (it.Name == GXConfigurations.Performance && !string.IsNullOrEmpty(it.Settings))
                        {
                            _settings = JsonSerializer.Deserialize<PerformanceSettings>(it.Settings);
                            StateHasChanged();
                            break;
                        }
                    }
                }
            });
            Notifier.Clear();
            Notifier.AddMenuItem(new GXMenuItem() { Text = Properties.Resources.Save, Icon = "oi oi-pencil", OnClick = OnSave });
            Notifier.AddMenuItem(new GXMenuItem() { Text = Properties.Resources.Cancel, Icon = "oi oi-action-undo", OnClick = OnCancel });
            Notifier.UpdateButtons();
            if (!string.IsNullOrEmpty(Parent?.Active?.Settings))
            {
                try
                {
                    _settings = JsonSerializer.Deserialize<PerformanceSettings>(Parent.Active.Settings);
                }
                catch (Exception)
                {
                    _settings = new PerformanceSettings();
                }
            }
        }
        catch (AccessTokenNotAvailableException exception)
        {
            exception.Redirect();
        }
        catch (Exception ex)
        {
            Notifier?.ProcessError(ex);
        }
        finally
        {
            Notifier?.ProgressEnd();
        }
    }

    /// <summary>
    /// Save values.
    /// </summary>
    private async void OnSave()
    {
        try
        {
            Notifier.ProgressStart();
            Notifier.ClearStatus();
            if (Parent?.Active == null)
            {
                throw new Exception(Properties.Resources.InvalidTarget);
            }
            Parent.Active.Settings = JsonSerializer.Serialize(_settings);
            ConfigurationUpdate arg = new ConfigurationUpdate();
            arg.Configurations = new GXConfiguration[] { Parent.Active };
            await Http.PostAsJson("api/Configuration/Update", arg);
            ClientHelpers.NavigateToLastPage(NavigationManager, Notifier);
        }
        catch (Exception ex)
        {
            Notifier?.ProcessError(ex);
        }
        finally
        {
            Notifier?.ProgressEnd();
        }
    }

    /// <summary>
    /// Cancel update.
    ///</summary>
    private void OnCancel()
    {
        ClientHelpers.NavigateToLastPage(NavigationManager, Notifier);
    }

    public void Dispose()
    {
        Notifier.RemoveListener(this);
    }
}
